package com.yupi.web.manager;

import cn.hutool.core.io.FileUtil;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.*;
import com.yupi.web.config.OBSClientConfig;
import com.yupi.web.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;

/**
 * Cos 对象存储操作
 *
 * @author wangfenghuan
 * @from 
 */
@Slf4j
@Component
public class ObsManager {

    @Resource
    private OBSClientConfig obsClientConfig;

    //文件名称（对象名称）
    private static  String fileName;

    @Resource
    private UserService userService;
    /**
     * 上传文件到华为云OBS
     * @param multipartFile
     * @return
     * @throws IOException
     */
    public String upload(MultipartFile multipartFile) throws IOException {
        // 获取上传的文件的输入流
        InputStream inputStream = multipartFile.getInputStream();

        // 避免文件覆盖
        String originalFilename = multipartFile.getOriginalFilename();
        fileName = multipartFile.getName()+  UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));

        // 创建ObsClient实例
        ObsClient obsClient = new ObsClient(obsClientConfig.getAccessKeyId(), obsClientConfig.getSecretAccessKey(), obsClientConfig.getEndpoint());

        try {
            // 上传文件到 OBS
            obsClient.putObject(obsClientConfig.getBucketName(), fileName, inputStream);

            // 文件访问路径
            String url = "https://" + obsClientConfig.getBucketName() + "." + obsClientConfig.getEndpoint() + "/" + fileName;
            // 把上传到OBS的路径返回
            return url;
        } catch (ObsException e) {
            // 处理异常
            throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
        } finally {
            // 关闭obsClient
            if (obsClient != null) {
                try {
                    obsClient.close();
                } catch (Exception e) {
                    // 忽略关闭时可能产生的异常
                }
            }
        }
    }

    /**
     * 下载文件并返回给前端
     * @param objectName
     * @return
     */
    public byte[] downLoad(String objectName){
        //初始化客户端
        ObsClient obsClient = new ObsClient(obsClientConfig.getAccessKeyId(), obsClientConfig.getSecretAccessKey(), obsClientConfig.getEndpoint());
        // 流式下载
        ObsObject obsObject = obsClient.getObject(obsClientConfig.getBucketName(), objectName);
        try {
            // 读取对象内容
            log.info ("Object content:");
            InputStream input = obsObject.getObjectContent();
            byte[] b = new byte[1024];
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            int len;
            while ((len = input.read(b)) != -1) {
                bos.write(b, 0, len);
            }
             log.info("getObjectContent successfully");
            byte[] file = bos.toByteArray();
            bos.close();
            input.close();
            return file;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void downloadToLocal(String objectName, String storePath){
        //初始化客户端
        ObsClient obsClient = new ObsClient(obsClientConfig.getAccessKeyId(), obsClientConfig.getSecretAccessKey(), obsClientConfig.getEndpoint());
        // 流式下载
        ObsObject obsObject = obsClient.getObject(obsClientConfig.getBucketName(), objectName);
        try {
            // 读取对象内容
            log.info ("Object content:");
            InputStream input = obsObject.getObjectContent();
            byte[] b = new byte[1024 * 1024 * 1024];
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            int len;
            while ((len = input.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            log.info("getObjectContent successfully");
            byte[] file = bos.toByteArray();
            //将字节数组写入到本地
            FileUtil.writeBytes(file, storePath);
            bos.close();
            input.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    public void delObject(String objectPrefix){
        //初始化客户端
        ObsClient obsClient = new ObsClient(obsClientConfig.getAccessKeyId(), obsClientConfig.getSecretAccessKey(), obsClientConfig.getEndpoint());
        String bucketName = obsClientConfig.getBucketName();


        String delObjectPrefix = objectPrefix;
        try {
            // 批量删除对象
            ListVersionsRequest request = new ListVersionsRequest(bucketName);
            // 每次批量删除5个对象
            request.setMaxKeys(5);
            request.setPrefix(delObjectPrefix);
            ListVersionsResult result;
            do {
                result = obsClient.listVersions(request);
                DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest(bucketName);
                // deleteRequest.setQuiet(true);
                // 注意此示例默认是详细模式，如果要使用简单模式，请添加本行代码
                for (VersionOrDeleteMarker v : result.getVersions()) {
                    // 获取对象和版本号
                    deleteRequest.addKeyAndVersion(v.getKey(), v.getVersionId());
                }
                if(deleteRequest.getKeyAndVersions().length > 0){
                    DeleteObjectsResult deleteResult = obsClient.deleteObjects(deleteRequest);
                    // 获取删除成功的对象
                    log.info("DeletedObjectResults:"+ deleteResult.getDeletedObjectResults());
                    // 获取删除失败的对象
                    log.error("ErrorResults:"+ deleteResult.getErrorResults());
                }else{
                    log.info("No object to delete");
                }
                request.setKeyMarker(result.getNextKeyMarker());
                // 如果没有开启多版本对象，就不需要设置VersionIdMarker
                request.setVersionIdMarker(result.getNextVersionIdMarker());
            } while (result.isTruncated());
            log.info("deleteObjects successfully");
        } catch (ObsException e) {
            log.info("deleteObjects failed");
            // 请求失败,打印http状态码
            log.error("HTTP Code:" + e.getResponseCode());
            // 请求失败,打印服务端错误码
            log.error("Error Code:" + e.getErrorCode());
            // 请求失败,打印详细错误信息
            log.error("Error Message:" + e.getErrorMessage());
            // 请求失败,打印请求id
            log.error("Request ID:" + e.getErrorRequestId());
            log.error("Host ID:" + e.getErrorHostId());
            // 遍历Map的entry,打印所有报错相关头域
            Map<String, String> headers = e.getResponseHeaders();
            if(headers != null){
                for (Map.Entry<String, String> header : headers.entrySet()) {
                    if(header.getKey().contains("error")){
                        log.info(header.getKey()+":"+header.getValue());
                    }
                }
            }
            e.printStackTrace();
        } catch (Exception e) {
            log.error("deleteObjects failed");
            // 其他异常信息打印
            e.printStackTrace();
        }
    }
}
